//  Created by 莫瑞权 on 2022/5/18.
//  Copyright © 2022 Talkfun. All rights reserved.
//
@objc public enum TFRatingType: Int {
    /**整颗星星*/
   case whole
    /**半颗星星*/
   case half
    /**无限制*/
   case unlimited
}

typealias TFLEEStarRating1vNBlock = (_ urrentScoreChange:CGFloat , _ key:String) -> Void

import UIKit

class TFLEEStarRating1vN: UIView {

    //默认高度
    @objc var key:String = ""

    @objc var tf_height:CGFloat = 0

    /**
     间距 (初始化后设置 默认 5.0)
     */
    @objc var spacing:CGFloat = 5
    /**
     已选中星星图片 (初始化后设置)
     */
    @objc var checkedImage:UIImage?
    {
        didSet{
            if (checkedImage != nil)
            {
                for i in 0..<self.checkedImagesView.subviews.count {
       
                    
                    let imageView = self.checkedImagesView.subviews[i] as! UIImageView
                    imageView.image = checkedImage;
                }
                
            }
        }
    }
    /**
     未选中星星图片 (初始化后设置)
     */
    @objc var uncheckedImage:UIImage?
    {
        didSet{
            if (uncheckedImage != nil)
            {
              
                for i in 0..<self.uncheckedImagesView.subviews.count {
       
                    
                    let imageView = self.uncheckedImagesView.subviews[i] as! UIImageView
                    imageView.image = uncheckedImage;
                }
                
           
                
            }
        }
    }
    /**
     最大分数 (初始化后设置 , 默认 5.0)
     */
    @objc var maximumScore:CGFloat = 5.0
    /**
     最小分数 (初始化后设置 , 默认 0.0)
     */
    @objc var minimumScore:CGFloat = 0.0
    /**
     启用点击 (初始化后设置 , 默认 NO)
     */
    @objc var touchEnabled:Bool = false
    {
        didSet{
            
            if(touchEnabled == true)
            {
                let tapGesture = UITapGestureRecognizer.init(target: self, action: #selector(tapGestureEvent))
                self.addGestureRecognizer(tapGesture)
            }
       
        
        }
    }
    @objc func tapGestureEvent(_ tap:UITapGestureRecognizer)
    {
        //CGPoint
        let point = tap.location(in: self)
        
        let point1 = self.pointToRatio(point)
        
        self.updateStarView(point1)

    }
    /**
     启用滑动 (初始化后设置 , 默认 NO)
     */
    @objc var slideEnabled:Bool = false
    {
        didSet{
            if(slideEnabled == true)
            {
                self.isUserInteractionEnabled = true
               let panGesture = UIPanGestureRecognizer.init(target: self, action: #selector(self.panGestureEvent))
                
                self.addGestureRecognizer(panGesture)
            }
    
        }
    }
    
    @objc func panGestureEvent(_ tap:UITapGestureRecognizer)
    {
        //CGPoint
        let point = tap.location(in: self)
        
        let point1 = self.pointToRatio(point)
        
        self.updateStarView(point1)
    }
    //用实际的大小
    @objc var actualSize:Bool = false
    
    @objc var starCount:NSInteger = 0
    /**
     评分类型 (初始化后设置 , 默认 RatingTypeWhole)
     */
    @objc var type:TFRatingType = .whole
    
    var currentScore:CGFloat = 0
    /**
     当前分数 (以上设置完毕后 , 再设置 , 默认 0.0)
     */
    @objc func  setCurrentScore(_ score:CGFloat)
    {
     
           var currentScore:CGFloat = score
            if (currentScore < self.minimumScore)
                
            {
                currentScore = self.minimumScore;
            }
            if (currentScore > self.maximumScore)
                
            {
                currentScore = self.maximumScore;
            }
            
            self.updateStarView((currentScore - self.minimumScore) / (self.maximumScore - self.minimumScore))
           
      
    }
    
    @objc var currentScoreChangeBlock:TFLEEStarRating1vNBlock?

    
    // 已选中星星图片视图
    @objc var checkedImagesView = UIView()

    // 未选中星星图片视图
    @objc var uncheckedImagesView = UIView()
    @objc var starSize:CGSize = CGSize(width: 0, height: 0 )
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.starCount = 5
        // 初始化数据
        self.initData()
        
        // 初始化子视图
        self.initSubViews()
      
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    func initData()
    {
        // 设置默认值
        self.spacing = 5.0
        
        self.minimumScore = 0.0
        
        self.maximumScore = 5.0
        
     
        
        self.type = .whole
        
        self.isUserInteractionEnabled = false
    }

    func initSubViews()
    {
  
        // 初始化已选中和未选中图片视图

        self.addSubview(self.uncheckedImagesView)
        
        self.checkedImagesView.clipsToBounds = true
        self.addSubview(self.checkedImagesView)
        
        // 循环初始化已选中和未选中子视图
        for i in stride(from: 0, to: self.starCount ,by: 1) {
        
            let uncheckedImage = UIImageView()
            uncheckedImage.image = self.uncheckedImage
            self.uncheckedImagesView.addSubview(uncheckedImage)
            
            let checkedImage = UIImageView()
            checkedImage.image = self.checkedImage
            self.checkedImagesView.addSubview(checkedImage)
        }
        
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        // 重新设置布局
        
        // 宽度或高度发生改变 更新子视图布局
        
        if (self.uncheckedImagesView.frame.size.width != self.frame.size.width ||
            self.uncheckedImagesView.frame.height != self.starSize.height) {
            
            self.uncheckedImagesView.frame = CGRect(x: 0, y: 0, width: self.frame.size.width, height: self.starSize.height)
            
            
            self.uncheckedImagesView.center = CGPoint(x: self.frame.size.width * 0.5, y: self.frame.size.height * 0.5)
           
            
            self.checkedImagesView.frame = CGRect(x: 0, y: self.uncheckedImagesView.frame.origin.y, width: self.checkedImagesView.frame.size.width, height: self.starSize.height)
            for i in 0..<self.starCount {
   
                
                let uncheckedImage = self.uncheckedImagesView.subviews[i] as! UIImageView
                
                let checkedImage = self.checkedImagesView.subviews[i] as! UIImageView
                
                var imageFrame:CGRect = CGRect(x:  self.spacing, y: 0, width: self.starSize.width, height: self.starSize.height)
                
                if i>0 {
                    imageFrame = CGRect(x: (self.starSize.width + self.spacing) * CGFloat(i) + self.spacing, y: 0, width: self.starSize.width, height: self.starSize.height)
                }
                
                uncheckedImage.frame = imageFrame
                
                checkedImage.frame = imageFrame
            }
            
        }
        
    }
    
    override var frame: CGRect
    {
        didSet{
            var newFrame = frame
            
            if (frame.size.width>0) {
          
                var size:CGFloat = 0
                
                let width:CGFloat = (frame.size.width - (CGFloat(self.starCount) + 1) * self.spacing) / CGFloat(self.starCount)
                
                if (width > 0) {
                    
                    size = width;
                }
                
                if (self.actualSize ) {
                    self.starSize = CGSize(width: frame.size.height, height: frame.size.height)
                }else{
        //              NSAssert(self.starCount * self.spacing < self.frame.size.width, @"间距过长 已超出视图大小");
                       self.starSize = CGSize(width: size, height: size)
                
                }
             
            }
            
            // 如果当前高度不等于于星星高度 则设置当前高度为星星高度
            
            if (frame.size.height != self.starSize.height){
                
                newFrame = CGRect(x: frame.origin.x, y: ( self.tf_height - self.starSize.height)/2, width: frame.size.width, height: self.starSize.height)
          
            }
            
            super.frame = newFrame
            
        }
    }

  
    func pointToRatio(_ point:CGPoint)->CGFloat
     {
        
        // 坐标 转 所选中的比例
        
         var ratio:CGFloat = 0.0
        
        if (self.spacing > point.x) {
            
            ratio = 0.0
            
        } else if (self.frame.size.width - self.spacing < point.x) {
            
            ratio = 1.0
            
        } else {
            
            /* 比例转换
             *
             * 当前点击位置在当前视图宽度中的比例 转换为 当前点击星星位置在全部星星宽度中的比例
             * 当前点击位置去除其中的间距宽度等于星星的宽度 point.x - 间距 = 所选中的星星宽度
             * 所选中的星星宽度 / 所有星星宽度 = 当前选中的比例
             */
            
            let itemWidth:CGFloat = self.spacing + self.starSize.width
            
            let icount:CGFloat = point.x / itemWidth
           
            let count:CGFloat =  CGFloat(floorf(Float(icount)))
            
            var added:CGFloat = (itemWidth * (icount - count))
            
           
            if added >= self.spacing {
                added = self.spacing
            }else
            {
                
            }
            let x:CGFloat = point.x - self.spacing * count - added
            
            ratio = x / (self.starSize.width * CGFloat(self.starCount));
        }
        
        return ratio
    }
    //#pragma mark - 更新星星视图 传入当前所选中的比例值
    func updateStarView(_ ratio1:CGFloat)
    {
        if ( ratio1 < 0 || ratio1 > 1)
        {
            
          
        }else{
            var ratio:CGFloat = ratio1
            var width:CGFloat = 0.0
            
            // 根据类型计算比例和宽度
            if self.type == .whole {
                ratio = CGFloat(ceilf(Float(CGFloat(self.starCount) * ratio)))
                
                width = self.starSize.width * ratio + (self.spacing * CGFloat(roundf(Float(ratio))))
                
            }else if (self.type == .half)
            {
                ratio = CGFloat(self.starCount) * ratio
                
                let z:CGFloat = CGFloat(floorf(Float(ratio)))
                
                let s:CGFloat = ratio - z
                
                if (s > 0.5)
                {
                    ratio = z + 1.0
                }
                
                if (s <= 0.5 && s >= 0.001){
                    ratio = z + 0.5
                }
                
                width = self.starSize.width * ratio + (self.spacing * CGFloat(roundf(Float(ratio))))
            }else if (self.type == .unlimited)
            {
                
                ratio = CGFloat(self.starCount) * ratio
                
                width = self.starSize.width * ratio + (self.spacing * CGFloat(ceilf(Float(ratio))))
            }
         
            // 设置宽度
            
            if (width < 0)
            {
                width = 0
            }
            
            if (width > self.frame.size.width)
            {
                width = self.frame.size.width
            }
            
            var checkedImagesViewFrame:CGRect = self.checkedImagesView.frame
            
            checkedImagesViewFrame.size.width = width
            
            self.checkedImagesView.frame = checkedImagesViewFrame
            
            // 设置当前分数
            
            let numRatio = NSDecimalNumber.init(string: String.init(format: "%0.4lf", ratio / CGFloat(self.starCount)))
            
            let numScore = NSDecimalNumber.init(string: String.init(format: "%0.4lf",  CGFloat(self.maximumScore - self.minimumScore)))
            
            let numResult = numRatio.multiplying(by: numScore)
          
            var currentScore:CGFloat = CGFloat(numResult.floatValue) + self.minimumScore
            
            if (currentScore < self.minimumScore)
            {
                currentScore = self.minimumScore
            }
                
            
            if (currentScore > self.maximumScore)
            {
                currentScore = self.maximumScore;
            }
                
            
            if (self.currentScore != currentScore) {
                
                self.currentScore = currentScore;

                if (self.currentScoreChangeBlock != nil)
                {
                    self.currentScoreChangeBlock!(self.currentScore,self.key)
                }
                    
                    
            }
            
       
        }
        
    }
}
